package JPetStore.web.servlet;

import JPetStore.domain.Account;
import JPetStore.domain.Category;
import JPetStore.domain.Language;
import JPetStore.persistence.AccountDao;
import JPetStore.persistence.CategoryDao;
import JPetStore.persistence.LanguageDao;
import JPetStore.persistence.impl.AccountDaoImpl;
import JPetStore.persistence.impl.CategoryDaoImpl;
import JPetStore.persistence.impl.LanguageDaoImpl;
import JPetStore.service.AccountService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

public class RegisterFormServlet extends HttpServlet {
    private static final String REGISTER_FORM = "/WEB-INF/jsp/account/NewAccountForm.jsp";
    private String value1;
    private String value2;
    Boolean isSame = false;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        CategoryDao categoryDao = new CategoryDaoImpl();
        List<Category> categories = categoryDao.getCategoryList();
        session.setAttribute("categories", categories); // 将类别列表存储在会话范围内
        LanguageDao languageDao = new LanguageDaoImpl();
        List<Language> languages = languageDao.getLanguageList();
        session.setAttribute("languages", languages);
        req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            HttpSession session = req.getSession();
            String userid = req.getParameter("userid");
            String password = req.getParameter("password");
            String repeatedPassword = req.getParameter("repeatedPassword");
            this.value1 = req.getParameter("vCode");
            this.value2 = (String) session.getAttribute("checkcode");

            // 验证用户名
            AccountService accountService = new AccountService();
            if (userid == null || userid.length() < 3 || userid.length() > 20 || !userid.matches("^[a-zA-Z0-9_-]+$")) {
                req.setAttribute("msg", "用户名长度应为3到20之间，并且只能包含字母、数字、下划线或连字符");
                req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
                return;
            }

            if (Character.isDigit(userid.charAt(0))) {
                req.setAttribute("msg", "用户名不能以数字开头");
                req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
                return;
            }

            if (accountService.is_repeat(userid)) {
                req.setAttribute("msg", "用户名已存在");
                req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
                return;
            }

            // 验证密码
            if (!password.matches("^[!@#\\$0-9a-zA-Z]+$") || !password.matches(".*[0-9].*") || password.matches("^\\d+$")) {
                req.setAttribute("msg", "密码必须包含数字，不能只包含数字，且只能包含字母、数字和特殊字符!@#$");
                req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
                return;
            }

            int passwordStrength = calculatePasswordStrength(password);
            if (passwordStrength < 1) {
                req.setAttribute("msg", "密码强度不足，请添加更多字符种类，例如大写字母、小写字母或特殊字符");
                req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
                return;
            }

            // 验证重复密码
            if (!Objects.equals(password, repeatedPassword)) {
                req.setAttribute("msg", "两次输入的密码不一致");
                req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
                return;
            }

            if (this.value1.isEmpty()) {
                req.setAttribute("msg", "验证码为空");
                req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
                return;
            } else if (value2.equalsIgnoreCase(value1)) {
                isSame = true;
            }

            if (isSame) {
                String firstName = req.getParameter("account.firstName");
                String lastName = req.getParameter("account.lastName");
                String email = req.getParameter("account.email");
                String phone = req.getParameter("account.phone");
                String address1 = req.getParameter("account.address1");
                String address2 = req.getParameter("account.address2");
                String city = req.getParameter("account.city");
                String state = req.getParameter("account.state");
                String zip = req.getParameter("account.zip");
                String country = req.getParameter("account.country");
                String languagePreference = req.getParameter("account.languagePreference");
                String favouriteCategoryId = req.getParameter("account.favouriteCategoryId");
                boolean listOption = Objects.equals(req.getParameter("account.listOption"), "1");
                boolean bannerOption = Objects.equals(req.getParameter("account.bannerOption"), "1");
                Account account = new Account();
                account.init(userid, userid, password, email, firstName, lastName, "OK", address1, address2, city, state, zip, country, phone, favouriteCategoryId, languagePreference, listOption, bannerOption);
                AccountDao accountDao = new AccountDaoImpl();
                accountDao.insertAccount(account);
                accountDao.insertProfile(account);
                accountDao.insertSignon(account);
                req.setAttribute("registerMsg", "注册成功！");
                req.getRequestDispatcher("/WEB-INF/jsp/account/signon.jsp").forward(req, resp);
            } else {
                req.setAttribute("msg", "验证码错误");
                req.getRequestDispatcher(REGISTER_FORM).forward(req, resp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private int calculatePasswordStrength(String password) {
        int level = 0;
        if (password.matches(".*[!@#$].*")) {
            level++;
        }
        if (password.matches(".*[a-z].*")) {
            level++;
        }
        if (password.matches(".*[A-Z].*")) {
            level++;
        }
        return level;
    }
}